#include "dirlist.h"
#include "path.h"
using namespace std;
#include <sys/types.h>
#include <sys/stat.h>

inline bool endsWith(string& s, string& q)
{
	int size_s = s.size();
	int size_q = q.size();
	
	if (size_s < size_q)
		return false;
		
	return s.substr(size_s - size_q, size_q) == q;
}

DirectoryListing::DirectoryListing(string path, string file_ext)
{
	Filename_Extension = file_ext;
	this->path = path;
	
	#ifdef _WIN32
	string search = path + "*";
	findhandle = FindFirstFile(search.c_str(), &finddata);
	Success = findhandle != INVALID_HANDLE_VALUE;
	Stored_Filename = finddata.cFileName;
	#else
	dhandle = opendir(path.c_str());
	Success = dhandle != NULL;
	#endif
}

DirectoryListing::~DirectoryListing()
{
	if (!Success)
		return;
		
	#ifdef _WIN32
	FindClose(findhandle);
	#else
	closedir(dhandle);
	#endif
}

std::string DirectoryListing::fullName(const std::string& s)
{
	return path + s;
}

bool DirectoryListing::operator()(string& s)
{
	if (!Success)
		return false;
		
	bool retval;
	
	do
	{
		#ifdef _WIN32
		if (Stored_Filename.size())
		{
			s = Stored_Filename;
			if (FindNextFile(findhandle, &finddata))
				Stored_Filename = finddata.cFileName;
				
			else
				Stored_Filename = "";
				
				retval = true;
		}
		else
			retval = false;
		#else
		current = readdir(dhandle);
		if (current)
		{
			s = current->d_name;
			retval = true;
		}
		else
			retval = false;
		#endif
	}
	while (retval == true && endsWith(s, Filename_Extension) == false);
	
	return retval;
}

bool DirectoryListing::NextDirectory(string& s)
{
	if (!Success)
		return false;
		
	bool retval;
#ifdef _WIN32
	struct stat fileinfo;
	do
	{
		if (Stored_Filename.size())
		{
			s = Stored_Filename;
			
			if (FindNextFile(findhandle, &finddata))
				Stored_Filename = finddata.cFileName;
			else
				Stored_Filename = "";
				
			retval = true;
		}
		else
			retval = false;
	}
	while (retval == true && (stat(fullName(s).c_str(), &fileinfo) == -1 || (fileinfo.st_mode & _S_IFDIR) == 0 || s == "." || s == ".." || s == "CVS" || s == ".svn"));
#else
	struct stat fileinfo;
	do
	{
		current = readdir(dhandle);
		if (current)
		{
			s = current->d_name;
			retval = true;
		}
		else
			retval = false;
	}
	while (retval == true && (stat(fullName(s).c_str(), &fileinfo) == -1 || !S_ISDIR(fileinfo.st_mode) || s == "." || s == ".." || s == "CVS" || s == ".svn"));
#endif

	return retval;
}
